import moment from 'moment';

const utils = {
    loading: false,
    //深度拷贝
    jsoncopy(obj) {
      if (!obj) {
        return null;
      }
      return JSON.parse(JSON.stringify(obj));
    },
    //检查对象是否为空
    oIsEmp(obj) {
      return Object.keys(obj).length === 0;
    },
    //深度拷贝
    deepClone(source) {
      const targetObj =
        Object.prototype.toString.call(source) === "[object Array]" ? [] : {}; // 判断复制的目标是数组还是对象
      for (const keys in source) {
        // 遍历目标
        if (source.hasOwnProperty(keys)) {
          //只拷贝自身属性，原型链上不考虑
          if (source[keys] && typeof source[keys] === "object") {
            // 如果值是对象，就递归一下
            targetObj[keys] =
              Object.prototype.toString.call(source[keys]) == "[object Array]"
                ? []
                : {};
            targetObj[keys] = utils.deepClone(source[keys]);
          } else {
            // 如果不是，就直接赋值
            targetObj[keys] = source[keys];
          }
        }
      }
      return targetObj;
    },
    /**
     *
     * @desc 防止重复执行 callback 中的代码
     * @param  {func} cb callback
     * @param  {int} time 设置多少时间后可以再次执行
     * @return
     */
    preventRepeat(cb, time) {
      if (typeof cb === "function") {
        try {
          if (this.loading) {
            return;
          } else if (this.loading === false) {
            this.loading = true;

            cb(this.loading);
            window.setTimeout(() => {
              this.loading = false;
            }, time);
          }
        } catch (err) {
          console.err(err);
          this.loading = false;
        }
      }
    },
    /**
     *
     * @desc 防止重复执行 callback 中的代码
     * @param  {func} cb(callback(func(resolve))) 回调中包含回调
     * @return
     */
    preventRepeatAsync(cb) {
      if (typeof cb === "function") {
        try {
          if (this.loading) {
            return;
          } else if (this.loading === false) {
            this.loading = true;
            const _this = this;

            function callback(func) {
              return new Promise(resolve => {
                func(resolve);
              });
            }

            async function asyncFun() {
              await cb(callback);
              _this.loading = false;
            }

            return asyncFun();
          }
        } catch (err) {
          console.error(err);
          this.loading = false;
        }
      }
    },
    /*
    * 防止重复提交 简化
    */
    preventRA(cb) {
      if (!cb) {
        throw new Error("请传入 callback");
        return;
      }
      this.preventRepeatAsync((callback) => callback((resolve) => {
        cb(resolve);
      }))
    },

    /**
     *
     * @desc 传入的数组指定位置交换顺序
     * @param  {int} start数组元素起始位置
     * @param  {int} end数组元素结束位置
     * @return {Array}
     */
    switchArr(arr, start, end) {
      const newArr = this.jsoncopy(arr);
      newArr[start] = [...newArr.splice(end, 1, newArr[start])[0]];
      return newArr;
    },

    /**
     *
     * @desc 在指定位置之后插入数组
     * @param  Array 待插入的数组
     * @param  index 指定位置
     * @param  obj 待插入数据
     * @return {Array}
     */
    insertArr(arr, index, obj) {
      const newArr = this.jsoncopy(arr);
      newArr.splice(index + 1, 0, obj);
      return newArr;
    },

    /**
     *
     * @desc 传入的数组 去重
     * @param  {Array} array 传入数组
     * @return {Array} 返回去掉重复项的数组
     */
    arrayPreventRepeat(array) {
      return Array.from(new Set(array));
    },

    /**
     *
     * @desc 传入的对象返回 数据类型
     * @return {string}   "String","Number","Array"
     */
    objType(obj) {
      return Object.prototype.toString.call(obj).slice(8, -1);
    },
    /**
     * @desc  转换星期
     */
    changeWeekData(int) {
      const week = {
        1: "周一",
        2: "周二",
        3: "周三",
        4: "周四",
        5: "周五",
        6: "周六",
        7: "周日",
      }
      return week[parseInt(int)];
    },
    /**
     * @desc  数字转汉字
     * @param int
     */
    changeIntData(int) {
      const obj = {
        1: "一",
        2: "二",
        3: "三",
        4: "四",
        5: "五",
        6: "六",
        7: "日",
      }
      return obj[parseInt(int)];
    },

    /**
     * @desc  格式化 html
     * @param string| HtmlElement  带html 元素的字符串
     * @return 取出其中的文字
     */
    formatHtml(str) {
      return str.replace(/<[^<>]+>/g, "")
    },


    /**
     * @desc  初始化数据，非空 转换
     *
     */
    initAjaxData(dataObj, model) {
      // 数据补齐
      const arrayObjClone = (dataObj, model) => {

        let newModel = utils.jsoncopy(model);
        const arrCopy = (dataObj, target) => {
          let copyData = target[0];
          for (let i = 1; i < dataObj.length; i++) {
            target.push(arrayObjClone(dataObj[i], copyData));
          }
          console.log(target);
          return target;
        }
        if (utils.objType(newModel) !== utils.objType(dataObj)) {
          console.log("数据类型不一致")
          return newModel;
        }
        if (Object.prototype.toString.call(dataObj) === "[object Array]") {
          newModel = arrCopy(dataObj, newModel);
        }
        if (Object.prototype.toString.call(dataObj) === "[object Object]") {
          for (const keys in dataObj) {
            // 遍历目标
            if (dataObj.hasOwnProperty(keys)) {
              //只拷贝自身属性，原型链上不考虑
              if (dataObj[keys] && utils.objType(dataObj[keys]) === "Array") {
                // 如果值是对象，就递归一下
                const data = arrCopy(dataObj[keys], newModel[keys]);
                newModel[keys] = data;
              }
            }
          }
        }

        return newModel;
      }

      //初始化数据，非空 转换
      const initAjaxCopy = (dataObj, model) => {

        // 判断复制的目标是数组还是对象
        const targetObj = Object.prototype.toString.call(model) === "[object Array]" ? [] : {};

        for (const keys in model) {
          // 遍历目标
          if (model.hasOwnProperty(keys)) {
            //只拷贝自身属性，原型链上不考虑
            if (model[keys] && typeof model[keys] === "object") {
              // 如果值是对象，就递归一下
              targetObj[keys] = Object.prototype.toString.call(model[keys]) == "[object Array]" ? [] : {};
              targetObj[keys] = initAjaxCopy(dataObj[keys], model[keys]);
            } else {
              // 如果不是空值，就直接赋值
              if (dataObj[keys]) {
                targetObj[keys] = dataObj[keys];
              } else {
                targetObj[keys] = model[keys];
              }
            }
          }
        }
        return targetObj;
      }

      const newModel = arrayObjClone(dataObj, model);
      const data = initAjaxCopy(dataObj, newModel);
      return data;
    },

    /**
     *
     * @desc   Array|obj 去除数组中重复的对象
     * @param  {Array} array 传入数组
     * @param {String} 去重的关键 key
     */
    removeDuplicateObj(array, key, callback) {
      let hash = {};
      let arr = utils.jsoncopy(array);
      arr = arr.reduce((acc, item) => {
        if (hash[item[key]]) {
          callback && callback(item[key]);
        } else {
          hash[item[key]] = true && acc.push(item);
        }
        return acc;
      }, []);
      return arr;
    },


    /**
     *
     * @desc   格式化时间
     * @param  {moment} moment时间对象
     * @param {String} 格式化后的时间
     */
    formatData(obj, f = "YYYY-MM-DD") {
      return moment(obj).format(f);
    },
    /**
     *
     * @desc   格式化时间
     * @param  {moment} moment时间对象
     * @param {String} 格式化后的时间
     */
    currentData(f = "YYYY-MM-DD") {
      return moment().format(f)
    },


  }
;


export default utils;



